﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using System.Collections.Concurrent;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using System.Threading.Tasks;
using Messenger.Models;

namespace Messenger.Hubs
{
    [Authorize]
    public class MessageHub : Hub
    {
        private static readonly ConcurrentDictionary<string, List<string>> _userConnections = new ConcurrentDictionary<string, List<string>>();

        private ApplicationDbContext db = new ApplicationDbContext();
        
        public void Send(string userBId, string message)
        {
            var userAName = Context.User.Identity.Name;
            var mgr = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
            var userAId = mgr.FindByEmail(userAName).Id;
   
            Message msg = new Message() { Text = message, FromId = userAId, ToId = userBId };
            msg = db.Messages.Add(msg);
            db.SaveChanges();

            var userBName = mgr.FindById(userBId).Email;

            List<string> connections;
            if (_userConnections.TryGetValue(userBName, out connections))
            {
                Clients.Clients(connections).addMessage(msg);
            }
        }

        public override Task OnConnected()
        {
            var connections = _userConnections.GetOrAdd(Context.User.Identity.Name, _ => new List<string>());
            lock (connections)
            {
                connections.Add(Context.ConnectionId);
            }
            return base.OnConnected();
        }
        
        public override Task OnDisconnected(bool stopCalled)
        {
            List<string> connections;
            if (_userConnections.TryGetValue(Context.User.Identity.Name, out connections))
            {
                lock (connections)
                {
                    connections.Remove(Context.ConnectionId);
                }
            }
            return base.OnDisconnected(stopCalled);
        }
    }
}